package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.dto.DeviceDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.DeviceDataVo;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private Client client;
    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 把产品存到redis中
     */
    @Override
    public void queryProductList() {
        QueryProductListRequest request = new QueryProductListRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setCurrentPage(1);
        request.setPageSize(100);
        QueryProductListResponse queryProductListResponse=null;
        try {
             queryProductListResponse = client.queryProductList(request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if(queryProductListResponse.getBody().getSuccess()){
            List<QueryProductListResponseBody.QueryProductListResponseBodyDataListProductInfo> productInfo = queryProductListResponse.getBody().getData().list.getProductInfo();
            redisTemplate.opsForValue().set("device:product", JSONUtil.toJsonStr(productInfo));
        }

    }

    /**
     * 拿所有产品
     * @return
     */
    @Override
    public List<ProductVo> allProductList() {
        String s = redisTemplate.opsForValue().get("device:product");
        List<ProductVo> list = JSONUtil.toList(s, ProductVo.class);
        return list;
    }

    /**
     * 注册设备
     * @param deviceDto
     */
    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //1.查询数据库中是否存在设备名称
        int count =  deviceMapper.queryDevice(deviceDto.getDeviceName());
        if (count>0){
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        //2.物联网新增设备
        RegisterDeviceRequest registerDeviceRequest = new RegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        registerDeviceRequest.setProductKey(deviceDto.getProductKey());
        registerDeviceRequest.setDeviceName(deviceDto.getDeviceName());
        RegisterDeviceResponse response =null;
        try {
             response = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //3.把设备信息存到数据库中
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(response.getBody().getData().getIotId());

        //产品名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse = null;

        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        //从iot中查出来产品名称设置产品名称
        if (queryProductResponse.getBody().getSuccess()){
            device.setProductName(queryProductResponse.getBody().getData().getProductName());
        }

        //获取设备类型---随身设备，将PhysicalLocationType设置成null或者-1
        if (device.getLocationType().equals(0)){
            device.setPhysicalLocationType(-1);
        }

        //存设备
        try {
            device.setHaveEntranceGuard(0);
            deviceMapper.insert(device);
        }catch (Exception e){
            //添加失败，删除iot中的设备
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setIotId(response.getBody().getData().getIotId());
            deleteDeviceRequest.setProductKey(deviceDto.getProductKey());
            deleteDeviceRequest.setDeviceName(deviceDto.getDeviceName());
            DeleteDeviceResponse deleteDeviceResponse =null;
            try {
                 deleteDeviceResponse = client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
        }

    }



    /**
     * 分页查询设备
     * @param
     * @return
     */
    @Override
    public PageResponse<DeviceVo> queryPage(Integer pageNum, Integer pageSize, String deviceName, String productKey, Integer locationType) {
        PageHelper.startPage(pageNum,pageSize);
        Page<DeviceVo> page = deviceMapper.queryPage(deviceName, productKey, locationType);
        return PageResponse.of(page,DeviceVo.class);
    }

    /**
     * 查询设备详情
     * @param deviceDto
     * @return
     */
    @Override
    public DeviceVo queryDeviceDetail(DeviceDto deviceDto) {
        //1.从数据库中查找设备
        DeviceVo deviceVo = deviceMapper.queryDeviceDetail(deviceDto.getIotId());
        //2.从物联网平台中查询设备详情
        QueryDeviceDetailRequest request = new QueryDeviceDetailRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setIotId(deviceDto.getIotId());
        request.setProductKey(deviceDto.getProductKey());
        QueryDeviceDetailResponse response = null;
        try {
            response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
        //3.将iot设备和数据库查出来的合并一块返回
        BeanUtil.copyProperties(data,deviceVo, CopyOptions.create().ignoreNullValue());
        return deviceVo;
    }

    /**
     * 查询指定设备物模型运行状态
     * @param
     * @return
     */
    @Override
    public ResponseResult queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse queryDevicePropertyStatusResponse = null;
        try {
            queryDevicePropertyStatusResponse = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData data = queryDevicePropertyStatusResponse.getBody().getData();
        return ResponseResult.success(data);
    }



    /**
     * 查询指定产品的物模型中的功能定义
     * @param
     * @return
     */
    @Override
    public ResponseResult queryThingModelPublished(QueryThingModelPublishedRequest request) {

        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryThingModelPublishedResponse queryThingModelPublishedResponse = null;
        try {
            queryThingModelPublishedResponse = client.queryThingModelPublished(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_THING_MODEL_PUBLISHED_ERROR);
        }
        QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData data = queryThingModelPublishedResponse.getBody().getData();
        return ResponseResult.success(data);
    }
    /**
     * 修改设备
     * @param deviceDto
     */
    @Override
    public void updateDevice(DeviceDto deviceDto) {
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        List<BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo> deviceNicknameInfo = new ArrayList<>();
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo data = new BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo();
        data.setIotId(deviceDto.getIotId());
        data.setProductKey(deviceDto.getProductKey());
        data.setNickname(deviceDto.getNickname());
        deviceNicknameInfo.add(data);
        request.setDeviceNicknameInfo(deviceNicknameInfo);
        BatchUpdateDeviceNicknameResponse batchUpdateDeviceNicknameResponse =null;
        try {
            batchUpdateDeviceNicknameResponse = client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        if (!batchUpdateDeviceNicknameResponse.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        deviceMapper.updateDevice(device);

    }

    /**
     * 删除设备
     * @param deviceDto
     */
    @Override
    public void deleteDevice(DeviceDto deviceDto) {
        DeleteDeviceRequest request = new DeleteDeviceRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setProductKey(deviceDto.getProductKey());
        request.setDeviceName(deviceDto.getDeviceName());
        request.setIotId(deviceDto.getIotId());
        DeleteDeviceResponse response = null;
        try {
            response = client.deleteDevice(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        deviceMapper.deleteDevice(deviceDto.getIotId());
    }

    /**
     * 设备开门
     * @param iotId
     */
    @Override
    public void deviceOpenDoor(String iotId) {
        QueryProductRequest request = new QueryProductRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductResponse queryProductResponse =null;
        try {
            queryProductResponse = client.queryProduct(request);
        } catch (Exception e) {

            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        if (!queryProductResponse.getBody().getSuccess()){
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        String productName = queryProductResponse.getBody().getData().getProductName();
        if ("门禁".equals(productName)){
            deviceMapper.deviceOpenDoor(iotId);
        }
    }


}
